--[[
    desc:堆数据 默认父节点<子节点  左节点 < 右节点
]]

local fauto = reload("fauto")
local class = reload("class")
local super = reload("super.basic")
local clear = reload("table.opt.clear")
local cmset = require("mset")

---重复使用仓库
local store = reload("store")
local newt, delt = store()

---@class vesselheap:super.basic @堆数据
local this = class(super)

---构造函数
function this:ctor(max)
    super.ctor(self)
    ---节点列表
    self._hash = {}

    ---自动增长
    ---@type fun():number
    self._fauto = fauto()

    ---数据凭证
    self._cid = cmset.create(max or false)
end

--数据清空
function this:clear()
    clear(self._hash)
    cmset.clear(self._cid)
end

function this:gcback()
    super.gcback(self)
    clear(self._hash)
    cmset.destroy(self._cid)
end

---生成节点
---@return any @节点
function this:create(ticks, data, auto)
    local node = newt(0, 4)
    auto = auto or self._fauto()
    node.ticks = ticks
    node.data = data
    node.auto = auto
    return node
end

---添加节点
---@param   ticks     number      @节点比较
---@param   data      any         @节点数据
---@return  number                @节点位置
function this:append(ticks, data)
    local node = self:create(ticks, data, nil)
    return self:insert(node)
end

---插入节点
---@param   node    any     @节点数据
---@return  number          @唯一标识
function this:insert(node)
    local hash = self._hash
    local auto = node.auto
    local tick = node.ticks
    hash[node.auto] = node
    cmset.insert(self._cid, auto, tick)
    return node.auto
end

---读取头部
function this:reder()
    local auto, _ = cmset.begin(self._cid)
    return self._hash[auto]
end

---删除头部
function this:fetch()
    local auto, _ = cmset.begin(self._cid)
    return self:delete(auto)
end

function this:delete(auto)
    local node = self._hash[auto]
    if node then
        self._hash[auto] = nil
        cmset.delete(self._cid, auto, node.ticks)
    end
    return node
end

function this:pop()
    return self:fetch()
end

---迭代函数
function this.next(t, k)
    if nil == k then
        k = cmset.begin(t._cid)
    else
        k = cmset.next(t._cid, k)
    end

    if not t._hash[k] then
        k = nil
    end
    return k, t._hash[k]
end

---迭代函数
function this:ipairs()
    clear(self._order)
    self:order(1)
    return self.next, self, nil
end

---迭代函数
function this:pairs()
    return self:ipairs()
end

---回收节点
function this:delt(node)
    delt(node)
end

return this
